﻿using LinFu.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SW.EF.Core
{
    public class LinFuDynamicProxyProvider : IAopProvider
    {
        private static ProxyFactory proxy = new ProxyFactory();

        public T CreateInstance<T>()
        {
            return proxy.CreateProxy<T>(new InvokeWrapper(Engine.IocProvider.Resolve<T>()));
        }
    }

    public class InvokeWrapper : IInvokeWrapper
    {
        System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();

        private DateTime _startTime;
        private object _target;

        public InvokeWrapper(object target)
        {
            this._target = target;
        }

        public void BeforeInvoke(InvocationInfo info)
        {
            _startTime = DateTime.Now;
            watch.Start();
        }

        public object DoInvoke(InvocationInfo info)
        {
            try
            {
                return info.TargetMethod.Invoke(this._target, info.Arguments);
            }
            catch (Exception ex)
            {
                Engine.LogProvider.LogError(info, _startTime, ex);
                throw ex;
            }
        }

        public void AfterInvoke(InvocationInfo info, object returnValue)
        {
            watch.Stop();
            Engine.LogProvider.LogInfo(info, this._startTime, watch.Elapsed);
        }
    }
}
